/*
Copyright 2010 Farent-Solutions Ltd.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

 */
package com.farent.solutions.plugins.aribaweb.awl.completion;

import java.util.List;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
import javax.swing.text.StyledDocument;
import org.netbeans.editor.BaseDocument;
import org.netbeans.modules.xml.schema.model.SchemaModel;
import org.netbeans.spi.editor.completion.CompletionProvider;
import org.netbeans.spi.editor.completion.CompletionResultSet;
import org.netbeans.spi.editor.completion.CompletionTask;
import org.netbeans.spi.editor.completion.support.AsyncCompletionQuery;
import org.netbeans.spi.editor.completion.support.AsyncCompletionTask;
import org.openide.util.Exceptions;
import org.netbeans.editor.SyntaxSupport;
import org.netbeans.editor.Utilities;
import org.netbeans.modules.xml.text.completion.XMLCompletionQuery;
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
import org.netbeans.spi.editor.completion.CompletionItem;

/**
 *
 * @author farouka
 */
public class AwlCompletionProvider implements CompletionProvider {

    @Override
    public CompletionTask createTask(int queryType, final JTextComponent component) {
        if (queryType != CompletionProvider.COMPLETION_QUERY_TYPE) {
            return null;
        }
        return new AsyncCompletionTask(new AsyncCompletionQuery() {

            @Override
            protected void query(CompletionResultSet completionResultSet, Document document, int caretOffset) {
                BaseDocument doc = (BaseDocument) document;
                SyntaxSupport syntaxSupport = Utilities.getSyntaxSupport(component);
                 XMLSyntaxSupport support = (syntaxSupport instanceof XMLSyntaxSupport ?
                    (XMLSyntaxSupport) syntaxSupport : null);

                String firstTag = CompletionUtil.getStartTag(component, doc );
                String prefix = CompletionUtil.getPrefixFromTag(firstTag);
                boolean supported = CompletionUtil.canProvideCompletion(component, doc );

                AwlCompletionContext context = new AwlCompletionContext
                        (CompletionUtil.getPrimaryFile(), support, caretOffset);
                context.initContext();
                context.initModels();
                org.netbeans.modules.xml.axi.Element findAXIElementAtContext = CompletionUtil.findAXIElementAtContext(context);
                CompletionUtil.getElements(context);
                String filter = null;
                int startOffset = caretOffset - 1;

                try {
                    final StyledDocument bDoc = (StyledDocument) document;
                    final int lineStartOffset = getRowFirstNonWhite(bDoc, caretOffset);
                    final char[] line = bDoc.getText(lineStartOffset, caretOffset - lineStartOffset).toCharArray();
                    final int whiteOffset = indexOfWhite(line);
                    filter = new String(line, whiteOffset + 1, line.length - whiteOffset - 1);
                    if (whiteOffset > 0) {
                        startOffset = lineStartOffset + whiteOffset + 1;
                    } else {
                        startOffset = lineStartOffset;
                    }
                } catch (BadLocationException ex) {
                    Exceptions.printStackTrace(ex);
                }

                if (filter.equals("<")) {
                    completionResultSet.addItem(new RootCompletionItem("a", startOffset, caretOffset));
                    completionResultSet.addItem(new RootCompletionItem("w", startOffset, caretOffset));
                    completionResultSet.addItem(new RootCompletionItem("t", startOffset, caretOffset));
                    AWCoreCompletionProvider provider = new AWCoreCompletionProvider();

                    SchemaModel model = provider.createMetaSchemaModel();
                    String model_state=model.getSchema().getElements().toString();
                    System.out.println("model_state="+model_state);

                } 
//                    else {
//                    Kind kind = whichKind(filter);
//                    switch ( kind ) {
//                        case ELEMENT:{
//                            AWCoreCompletionProvider provider = new AWCoreCompletionProvider();
//                            completionResultSet.addAllItems(provider.getResults());
//                            break;
//                        }
//                        case ATTRIBUTE:{
//                            break;
//                        }
//                        case VALUE:{
//                            break;
//                        }
//                        case SPACE:{
//
//                        }
//                    }
//                }
                completionResultSet.finish();
            }
        }, component);
    }

    @Override
    public int getAutoQueryTypes(JTextComponent component, String typedText) {
        return 0;
    }

    static class Query extends AsyncCompletionQuery {
        private static final XMLCompletionQuery QUERY = new XMLCompletionQuery();
        private JTextComponent component;
        private boolean ENABLED = true;

        @Override
        protected void prepareQuery(JTextComponent component) {
            this.component = component;
        }

        @Override
        protected void query(CompletionResultSet resultSet, Document doc, int caretOffset) {
            SyntaxSupport syntaxSupport = Utilities.getSyntaxSupport(component); // fix for issue #185876
            XMLSyntaxSupport support = ( syntaxSupport instanceof XMLSyntaxSupport ?
                (XMLSyntaxSupport) syntaxSupport : null);
            if (!ENABLED || support == null) {
                resultSet.finish();
                return;
            }

            List<CompletionItem> items = QUERY.query(component, caretOffset, support);
            if(items != null) resultSet.addAllItems(items);
            resultSet.finish();
        }
    }

    static int getRowFirstNonWhite(StyledDocument doc, int offset)
            throws BadLocationException {
        Element lineElement = doc.getParagraphElement(offset);
        int start = lineElement.getStartOffset();
        while (start + 1 < lineElement.getEndOffset()) {
            try {
                if (doc.getText(start, 1).charAt(0) != ' ') {
                    break;
                }
            } catch (BadLocationException ex) {
                throw (BadLocationException) new BadLocationException(
                        "calling getText(" + start + ", " + (start + 1)
                        + ") on doc of length: " + doc.getLength(), start).initCause(ex);
            }
            start++;
        }
        return start;
    }

    static int indexOfWhite(char[] line) {
        int i = line.length;
        while (--i > -1) {
            final char c = line[i];
            if (Character.isWhitespace(c)) {
                return i;
            }
        }
        return -1;
    }


    enum Kind {
        ELEMENT,
        ATTRIBUTE,
        VALUE,
        SPACE;
    }

    Kind whichKind(String value){
        return Kind.ELEMENT;
    }
}
